home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / misc / emu / msh-156.lha / syslog / syslogd.c < prev    next >
C/C++ Source or Header  |  1994-10-24  |  9KB  |  473 lines

  1. /*-
  2.  * $Id: syslogd.c,v 1.1 1994/10/24 20:36:30 Rhialto Exp $
  3.  *
  4.  * $Log: syslogd.c,v $
  5.  * Revision 1.1  1994/10/24  20:36:30  Rhialto
  6.  * Initial revision
  7.  *
  8.  * DEBUGGING LOG DEAMON
  9. -*/
  10.  
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <stdlib.h>
  14. #ifndef EXEC_TASKS_H
  15. #include <exec/tasks.h>
  16. #endif
  17. #ifndef EXEC_MEMORY_H
  18. #include <exec/memory.h>
  19. #endif
  20. #ifndef LIBRARIES_DOSEXTENS_H
  21. #include <libraries/dosextens.h>
  22. #endif
  23. #include <clib/exec_protos.h>
  24. #include <clib/dos_protos.h>
  25. #include "syslog_private.h"
  26.  
  27. Local char *TaskName(struct Process *task);
  28. Local void Logger(void);
  29. Local struct LogPort *CreateLogPort(void);
  30. Local void DeleteLogPort(struct LogPort *logport);
  31. Local void OpenFile(int number, char *name);
  32. Local void CloseFile(int number);
  33. Local void CloseFiles(void);
  34. Local void ShowFile(int number);
  35. Local void ShowFiles(void);
  36. Local void putgetmsg(struct LogMsg *msg);
  37. Local void QuitLogging(void);
  38.  
  39.  
  40. #define MODE_READWRITE        1004L
  41. #define DISABLE         /* Disable(); */
  42. #define ENABLE            /* Enable(); */
  43.  
  44.  
  45. struct LogPort *LogPort;
  46. char        logportname[] = "syslog";
  47. int        OurLogPort;
  48. char        nullstring[] = "(null)";
  49.  
  50. #ifdef MANX_C
  51. /*
  52.  * vsprintf implementatation for Manx C compiler 3.x
  53.  */
  54.  
  55. static char    *sbuffer;
  56.  
  57. static int
  58. putchr(ch)
  59. int        ch;
  60. {
  61.     return (unsigned char) (*sbuffer++ = ch);
  62. }
  63.  
  64. int
  65. vsprintf(s, fmt, arg)
  66. char           *s;
  67. char           *fmt;
  68. void           *arg;
  69. {
  70.     int         result,
  71.             format();
  72.  
  73.     sbuffer = s;
  74.     result = format(putchr, fmt, arg);
  75.     *sbuffer = '\0';
  76.  
  77.     return result;
  78. }
  79. #endif
  80.  
  81. /*
  82.  * TaskName(). Returns the name of a task, including CLI command name
  83.  * if applicable.
  84.  *
  85.  * The result is a static buffer which is overwritten on each call.
  86.  */
  87.  
  88. char           *
  89. TaskName(task)
  90. struct Process *task;
  91. {
  92.     static char     name[128];
  93.     char       *s;
  94.  
  95.     strncpy(name, "Task ", sizeof(name));
  96.  
  97.     s = task->pr_Task.tc_Node.ln_Name;
  98.     if (s == NULL)
  99.     s = nullstring;
  100.     strncat(name, s, sizeof(name));
  101.  
  102.     if (task->pr_Task.tc_Node.ln_Type == NT_PROCESS) {
  103.     strncpy(name, "Proc", 4);
  104.     if (task->pr_CLI) {
  105.         struct CommandLineInterface *cli;
  106.         int         len;
  107.  
  108.         strncpy(name, "CLI ", 4);
  109.         strncat(name, ", ", sizeof(name));
  110.  
  111.         cli = (struct CommandLineInterface *) BADDR(task->pr_CLI);
  112.         s = (char *) BADDR(cli->cli_CommandName);
  113.         if (s) {
  114.         len = strlen(name) + (unsigned char) *s;
  115.         s++;
  116.         } else {
  117.         s = nullstring;
  118.         len = strlen(name) + strlen(s);
  119.         }
  120.         len++;
  121.         if (len > sizeof(name))
  122.         len = sizeof(name);
  123.         strncat(name, s, len);
  124.     }
  125.     }
  126.  
  127.     name[sizeof(name) - 1] = '\0';
  128.     return name;
  129. }
  130.  
  131.  
  132. char        logmessage[512];
  133.  
  134. void
  135. Logger()
  136. {
  137.     register struct LogMsg *msg;
  138.     struct Process *sigtask;
  139.     int         done;
  140.     long        len;
  141.  
  142.  
  143.     done = 0;
  144.     while (!done) {
  145.     WaitPort(&LogPort->lp_MsgPort);
  146.     msg = (struct LogMsg *) GetMsg(&LogPort->lp_MsgPort);
  147.     sigtask = (struct Process *)msg->lm_Msg.mn_ReplyPort;
  148.  
  149.     switch (msg->lm_Msg.mn_Length) {
  150.     case SYSLOG_PRINT:
  151.         sprintf(logmessage, "%08lx: ", sigtask);
  152.         len = 10 + vsprintf(logmessage + 10,
  153.                 msg->lm_Format, msg->lm_Args);
  154.  
  155.         break;
  156.     case SYSLOG_START:
  157.         LogPort->lp_OpenCount++;
  158.         len = sprintf(logmessage, "%08lx start (%s)\n", sigtask,
  159.               TaskName(sigtask));
  160.         break;
  161.     case SYSLOG_END:
  162.         LogPort->lp_OpenCount--;
  163.         len = sprintf(logmessage, "%08lx end   (%s)\n", sigtask,
  164.               TaskName(sigtask));
  165.         break;
  166.     case SYSLOG_QUIT:
  167.         if (LogPort->lp_OpenCount == 0) {
  168.         done = 1;
  169.         }
  170.         len = sprintf(logmessage, "%08lx quit  (%s) (%s)\n", sigtask,
  171.               TaskName(sigtask),
  172.               done ? "done" : "not done");
  173.         break;
  174.     default:
  175.         len = sprintf(logmessage, "%08lx unknown request %d (%s)\n",
  176.               sigtask, msg->lm_Msg.mn_Length,
  177.               TaskName(sigtask));
  178.         break;
  179.     }
  180.     if (len) {
  181.         int         i;
  182.         struct LogFile *lf;
  183.  
  184.         for (i = 0, lf = LogPort->lp_LogFile; i < MAXLOGS; i++, lf++) {
  185.         if ((lf->lf_FileHandle != 0) &&
  186.             !(lf->lf_Flags & LF_DISABLED)) {
  187.             Write(lf->lf_FileHandle, logmessage, len);
  188.         }
  189.         }
  190.     }
  191.     /*
  192.      * Sort-of Reply the message to the sender.
  193.      */
  194.  
  195.     msg->lm_Msg.mn_Node.ln_Type = NT_REPLYMSG;
  196.     Signal((struct Task *)sigtask, DEBUGSIGMASK);
  197.     }
  198.  
  199.     RemPort(&LogPort->lp_MsgPort);
  200. }
  201.  
  202. struct LogPort *
  203. CreateLogPort()
  204. {
  205.     BYTE        sigbit;
  206.     struct LogPort *logport;
  207.  
  208.     if (logport = (struct LogPort *) FindPort(logportname)) {
  209.     OurLogPort = 0;
  210.     return logport;
  211.     }
  212.  
  213.     if ((sigbit = AllocSignal(-1L)) == -1) {
  214.     return NULL;
  215.     }
  216.     logport = AllocMem((long) sizeof (*logport), MEMF_CLEAR | MEMF_PUBLIC);
  217.     if (logport == NULL) {
  218.     FreeSignal(sigbit);
  219.     return NULL;
  220.     }
  221.     logport->lp_MsgPort.mp_Node.ln_Name = logportname;
  222.     logport->lp_MsgPort.mp_Node.ln_Pri = 0;
  223.     logport->lp_MsgPort.mp_Node.ln_Type = NT_MSGPORT;
  224.  
  225.     logport->lp_MsgPort.mp_Flags = PA_SIGNAL;
  226.     logport->lp_MsgPort.mp_SigBit = sigbit;
  227.     logport->lp_MsgPort.mp_SigTask = FindTask(NULL);
  228.  
  229.     OurLogPort = 1;
  230.     AddPort(&logport->lp_MsgPort);
  231.  
  232.     return logport;
  233. }
  234.  
  235. void
  236. DeleteLogPort(logport)
  237. struct LogPort *logport;
  238. {
  239.     struct LogMsg *msg;
  240.  
  241.     while (msg = GetMsg(&LogPort->lp_MsgPort)) {
  242.     struct Task    *sigtask;
  243.  
  244.     sigtask = (struct Task *)msg->lm_Msg.mn_ReplyPort;
  245.     msg->lm_Msg.mn_Node.ln_Type = NT_REPLYMSG;
  246.     Signal(sigtask, DEBUGSIGMASK);
  247.     }
  248.  
  249.     logport->lp_MsgPort.mp_Node.ln_Type = 0xFF;
  250.     logport->lp_MsgPort.mp_MsgList.lh_Head = (struct Node *) - 1;
  251.  
  252.     FreeSignal(logport->lp_MsgPort.mp_SigBit);
  253.  
  254.     FreeMem(logport, (long) sizeof (*logport));
  255. }
  256.  
  257. void
  258. OpenFile(number, name)
  259. int        number;
  260. char           *name;
  261. {
  262.     struct LogFile *lf;
  263.  
  264.     if (number < 0) {
  265.     int        i;
  266.  
  267.     for (i = 0, lf = LogPort->lp_LogFile; i < MAXLOGS; i++, lf++) {
  268.         if (lf->lf_FileHandle == NULL) {
  269.         number = i;
  270.         break;
  271.         }
  272.     }
  273.     }
  274.     if (number >= 0 && number < MAXLOGS) {
  275.     BPTR        fh;
  276.  
  277.     lf = &LogPort->lp_LogFile[number];
  278.     fh = lf->lf_FileHandle;
  279.     if (fh) {
  280.         Close(fh);
  281.     }
  282.     strncpy(lf->lf_FileName, name, sizeof(lf->lf_FileName) - 1);
  283.     fh = Open(name, MODE_READWRITE);
  284.     if (fh == 0) {
  285.         fh = Open(name, MODE_NEWFILE);
  286.     }
  287.     if (fh) {
  288.         Seek(fh, 0L, OFFSET_END);
  289.     }
  290.     lf->lf_FileHandle = fh;
  291.     }
  292. }
  293.  
  294. void
  295. CloseFile(number)
  296. int        number;
  297. {
  298.     if (number >= 0 && number < MAXLOGS) {
  299.     BPTR        fh;
  300.  
  301.     fh = LogPort->lp_LogFile[number].lf_FileHandle;
  302.     if (fh) {
  303.         Close(fh);
  304.         LogPort->lp_LogFile[number].lf_FileHandle = 0;
  305.     }
  306.     }
  307. }
  308.  
  309. void
  310. CloseFiles()
  311. {
  312.     int         i;
  313.  
  314.     for (i = 0; i < MAXLOGS; i++) {
  315.     CloseFile(i);
  316.     }
  317. }
  318.  
  319. void
  320. ShowFile(number)
  321. int        number;
  322. {
  323.     struct LogFile *lf;
  324.  
  325.     if (number >= 0 && number < MAXLOGS) {
  326.     char *filename;
  327.  
  328.     lf = &LogPort->lp_LogFile[number];
  329.     filename = lf->lf_FileName;
  330.     if (filename == NULL)
  331.         filename = nullstring;
  332.  
  333.     printf("File %2d FileHandle: %8lx Flags: %02lx Name: '%s'\n",
  334.            number, lf->lf_FileHandle, lf->lf_Flags, filename);
  335.     }
  336. }
  337.  
  338. void
  339. ShowFiles()
  340. {
  341.     int         i;
  342.  
  343.     for (i = 0; i < MAXLOGS; i++) {
  344.     ShowFile(i);
  345.     }
  346. }
  347.  
  348. static void
  349. putgetmsg(msg)
  350. struct LogMsg *msg;
  351. {
  352.     long        OldSignal;
  353.  
  354.     msg->lm_Msg.mn_ReplyPort = (void *)FindTask(NULL);
  355.     /* Get original state of the signal, and clear it */
  356.     DISABLE();
  357.     OldSignal = SetSignal(0L, DEBUGSIGMASK);
  358.     ENABLE();
  359.     PutMsg(&LogPort->lp_MsgPort, &msg->lm_Msg);
  360.     for (;;) {
  361.     Wait(DEBUGSIGMASK);
  362.     if (msg->lm_Msg.mn_Node.ln_Type == NT_REPLYMSG)
  363.         break;
  364.     /* The signal was not for us, so set it when we're finished */
  365.     OldSignal = DEBUGSIGMASK;
  366.     }
  367.     /* Restore would-have-been state of the signal */
  368.     SetSignal(OldSignal, DEBUGSIGMASK);
  369. }
  370.  
  371. void
  372. QuitLogging(void)
  373. {
  374.     struct LogMsg   logmsg;
  375.  
  376.     logmsg.lm_Msg.mn_Length = SYSLOG_QUIT;
  377.  
  378.     putgetmsg(&logmsg);
  379. }
  380.  
  381. int
  382. main(argc, argv)
  383. int        argc;
  384. char          **argv;
  385. {
  386.     int         ac;
  387.     char      **av;
  388.     char       *avv;
  389.     int         filenr;
  390.     int         i;
  391.  
  392.     LogPort = CreateLogPort();
  393.     if (OurLogPort) {
  394.     OpenFile(0, "*");
  395.     }
  396.  
  397.     ac = --argc;
  398.     av = ++argv;
  399.  
  400.     filenr = -1;
  401.  
  402.     while (ac) {
  403.     if (av[0][0] == '-') {
  404.         avv = &av[0][1];
  405.         while (avv[0]) {
  406.         switch (avv[0]) {
  407.         case 'c':
  408.             i = atoi(&avv[1]);
  409.             if (0 < i && i < MAXLOGS) {
  410.             CloseFile(i);
  411.             }
  412.             break;
  413.         case 'd':
  414.             i = atoi(&avv[1]);
  415.             if (0 <= i && i < MAXLOGS) {
  416.             LogPort->lp_LogFile[i].lf_Flags ^= LF_DISABLED;
  417.             }
  418.             break;
  419.         case 'l':
  420.             ShowFiles();
  421.             break;
  422.         case 'q':
  423.             if (OurLogPort) {
  424.             RemPort(&LogPort->lp_MsgPort);
  425.             } else {
  426.             QuitLogging();
  427.             }
  428.             goto quit;
  429.         case 'r':
  430.             i = atoi(&avv[1]);
  431.             if (0 <= i && i < MAXLOGS) {
  432.             LogPort->lp_LogFile[i].lf_Flags = 0;
  433.             }
  434.             break;
  435.         case '-':
  436.             filenr = -1;
  437.             break;
  438.         default:
  439.             if ('0' <= avv[0] && avv[0] <= '9') {
  440.             filenr = atoi(avv);
  441.             goto break_options;
  442.             }
  443.         }
  444.         avv++;
  445.         }
  446.     } else {
  447.         /*
  448.          * Assume all other non-option arguments
  449.          * are file names to be opened
  450.          */
  451.         OpenFile(filenr, av[0]);
  452.         if (filenr >= 0) {
  453.         filenr++;
  454.         }
  455.     }
  456. break_options:
  457.     av++;
  458.     ac--;
  459.     }
  460.  
  461.     if (OurLogPort) {
  462.     Logger();
  463.     }
  464.  
  465. quit:
  466.     if (OurLogPort) {
  467.     CloseFiles();
  468.     DeleteLogPort(LogPort);
  469.     }
  470.  
  471.     return 0;
  472. }
  473.